<?php

namespace App\Http\Controllers\Api;

use App\Modules\Order\Models\Order;
use App\Modules\Rebate\Models\Rebate;
use App\Modules\User\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class RebateController extends ApiController
{
    public function getDetail(Request $request)
    {
        $this->validate($request, [
            'start'     => "nullable|date",
            'end'       => "nullable|date",
            'offset'    => 'nullable|integer',
            'count'     => 'nullable|integer',
            'status'    => 'nullable|string',
            'is_unlock' => 'nullable|boolean',
            'search'    => 'nullable|string',
        ]);

        $start    = $request->input('start');
        $end      = $request->input('end');
        $offset   = $request->input('offset');
        $count    = $request->input('count');
        $status   = $request->input('status');
        $isUnlock = $request->input('is_unlock', 0);
        $search   = $request->input('search');

        $user = $this->getUser();
        $query = Rebate::query()
            ->where('rebates.user_id', $user->id);
        if (!is_null($status)) {
            $query->where('rebates.status', $status);
        }
        if (!is_null($start)) {
            $query->where('rebates.created_at', ">", $start);
        }

        if ($isUnlock) {
            $query->where('rebates.level', 1);
        }

        if (!is_null($end)) {
            $query->where('rebates.created_at', "<", $end);
        }

        $query->where('rebates.withdrawal_time', "<", date('Y-m-d H:i:s'));

        $rebate = $query->orderBy('rebates.created_at', 'desc')
            ->join('users as buyer', 'buyer.id', '=', 'rebates.buyer_id')
            ->when(!is_null($search), function ($query) use ($search) {
                return $query->where(function ($q) use ($search) {
                    return $q->where('buyer.name', 'like', "%".$search."%")
                        ->orWhere('buyer.mobile', 'like', "%".$search."%");
                });
            })
            ->select("rebates.*", "buyer.nickname", "buyer.avatar", "buyer.name as buyer_name", "buyer.mobile as mobile")
            ->offset( $offset)
            ->limit($count)
            ->get();
        $orders = Order::query()
            ->whereIn('id', $rebate->pluck('link_id')->all())
            ->get()
            ->keyBy('id');
        $referrers = User::query()
            ->whereIn('id', $orders->pluck('referrer_id')->all())
            ->get()
            ->keyBy('id');
        $transferUser = User::query()
            ->whereIn('id', $rebate->pluck('transfer_user_id')->all())
            ->pluck('nickname', 'id')
            ->all();
        $re = $rebate->map(function ($item) use($orders, $referrers, $transferUser) {

            $order = $orders->get($item->link_id);
            $referrer = $referrers->get($order->referrer_id??null);
            if ($order->type == 'package') {
                $orderCover = $order->cover;
                $number     = 1;
                $price      = $item->original_price;
            } else {
                $detail     = collect($order->detail)->keyBy('good_name');
                $tmp        = $detail->get($item->title, []);
                $orderCover = $tmp['order_cover'];
                $number     = $tmp['number'];
                $price      = $tmp['price'];
            }
            if ($item->status == Rebate::STATUS_FINISH) {
                $rebateStatus = Rebate::$withdrawalStatusShow[$item->withdrawal_status];
            } else {
                $rebateStatus = Rebate::$statusShow[$item->status];
            }
            return [
                'id'               => $item->id,
                'title'            => $item->title,
                'nickname'         => $item->nickname,
                'name'             => $item->buyer_name,
                'order_name'       => $order->name,
                'avatar'           => $item->avatar,
                'money'            => $item->money,
                'order_cover'      => $orderCover,
                'order_status'     => $order->status,
                'goods_number'     => $number,
                'price'            => $price,
                'referrer'         => $referrer->name??null,
                'created_at'       => $item->created_at->toDateTimeString(),
                'status'           => $item->status,
                'rebate_status'    => $rebateStatus,
                'mobile'           => $item->mobile,
                'is_transfer'      => $item->is_transfer,//该记录是否为转赠过的，1是0否
                // 'transfer_user_id' => $item->transfer_user_id,//发起转赠的用户ID（如果该记录有转赠操作，user_id即为接收转赠的用户ID，若没有转赠操作，user_id即为原用户）
                'transfer_user'    => isset($transferUser[$item->transfer_user_id]) ? $transferUser[$item->transfer_user_id] : '',//发起转赠的用户昵称
                // 'transfer_time'    => $item->transfer_time,//转赠时间
                'withdrawal_time'  => $item->withdrawal_time,
            ];
        });
        return $this->success($re);
    }

    public function teamStatistics()
    {
        $user = $this->getUser();
        $re = [
            'achievement' => 0,
            'income' => 0,
            'share' => 0
        ];
        $income = Rebate::query()
            ->where('user_id', $user->id)
            ->where('status', Rebate::STATUS_ISSUED)
            ->sum('money');
        $achievement = Order::query()
            ->where('referrer_id', $user->id)
            ->where('status', Order::STATUS_PAID)
            ->sum('price');
        $share = User::query()
            ->where('referrer_id', $user->id)
            ->sum('share');
        $re = [
            'achievement' => $income,
            'income' => $achievement,
            'share' => $share,
        ];
        return $this->success($re);
    }

    public function teamList(Request $request)
    {
        $this->validate($request, [
            'offset' => 'integer',
            'count' => 'integer',
        ]);
        $offset = $request->input('offset', 0);
        $count = $request->input('count', 10);
        $user = $this->getUser();

        $referrer = User::query()
            ->where('referrer_id', $user->id)
            ->offset($offset)
            ->limit($count)
            ->get();
        $rebate = Rebate::query()
            ->where(['user_id', $user->id])
            ->where('status', Rebate::STATUS_ISSUED)
            ->selectRaw("sum(money) as money, buyer_id")
            ->groupBy('buyer_id')
            ->get();
        $re = $referrer->map(function ($item) use($rebate) {
            $tmp = $rebate->get($item->buyer_id);
            return [
                'id'       => $item->id,
                'nickname' => $item->nicknaem,
                'avatar'   => $item->avatar,
                'income'   => $tmp->money??0,
            ];
        });
        return $this->success($re);
    }

    /**
     * 数据统计 (rebates表)
     *
     * 待审核    type = init;    status = init
     * 待提现    type = issued;  status = issued
     * 提现中    type = ing;     status = finish && withdrawal_status = pending
     * 累计提现  type = total;   withdrawal_status = success
     */
    public function count(Request $request){
        $user = $this->getUser();

        $type = strip_tags($request->input('type'));
        $aWhere = [];
        switch ($type) {
            case 'init':
                // 待审核
                $aWhere['status'] = 'init';
                break;

            case 'issued':
                // 待提现
                $aWhere['status'] = 'issued';
                break;

            case 'ing':
                // 提现中
                $aWhere['status'] = 'finish';
                $aWhere['withdrawal_status'] = 'pending';
                break;

            case 'total':
                // 累计提现
                $aWhere['withdrawal_status'] = 'success';
                break;
            
            default:
                break;
        }
        $aWhere['user_id'] = $user->id;

        $rebate = Rebate::query()
            ->selectRaw('sum(money) as money')
            ->where($aWhere)
            ->get();

        return $this->success($rebate);  

    }

    /**
     * 发起转增
     */
    public function transfer(Request $request){
        $this->validate($request, [
            'user_id' => 'nullable|integer',
            'id'      => 'nullable|integer',
        ]);

        $user_id = $request->input('user_id');//接受转增的用户id
        $id      = $request->input('id');//当前记录的id
        
        $userOld = $this->getUser();//查询当前用户
        $userNew = User::query()->where('id', $user_id)->first();

        // 当前转赠的记录
        $data = Rebate::query()
            ->where('id', $id)
            ->where('user_id', $userOld->id)
            ->where('status', 'issued')
            ->first();

        if(empty($data))
            return $this->fail('参数有误，未查到相关数据');
        
        DB::beginTransaction();
        try {
            // 修改相关信息
            // 如果该记录有转赠操作，user_id即为接收转赠的用户ID，若没有转赠操作，user_id即为原用户
            $data->user_id          = $userNew->id;
            $data->is_transfer      = 1;//该记录是否为转赠的内容，1是0否
            $data->transfer_user_id = $userOld->id;//发起转赠的用户ID
            $data->transfer_time    = date('Y-m-d H:i:s');
            $data->save();

            // 发起转增的用户相应金额减少
            $accountOld = $userOld->getAccount();
            $accountOld->decreaseMoney($data->money, 'transfer', '发起转赠', '该用户发起转赠，转赠给用户：'.$userOld->id);

            // 接受转增的用户相应金额增加
            $accountNew = $userNew->getAccount();
            $accountNew->incrementMoney($data->money, 'transfer', '接受转赠', '该用户接受转赠，转赠来自用户：'.$userNew->id);

            DB::commit();
        } catch (\Exception $e) {
            throw $e;
            DB::rollBack();
        }

        return $this->success($data);
    }

    /**
     * 查询用户
     */
    public function queryUser(Request $request){
        $this->validate($request, [
            'search' => 'nullable',
            'offset' => 'nullable|integer',
            'count'  => 'nullable|integer',
        ]);

        $search = $request->input('search');
        $offset = $request->input('offset', 0);
        $count  = $request->input('count', 10);

        $query = User::query();
        
        if (!empty($search)) {
            $query->where(function ($query) use ($search) {
                return $query->where('nickname', 'like', '%' . $search . '%')
                    ->orWhere('mobile', 'like', '%' . $search . '%')
                    ->orWhere('name', 'like', '%' . $search . '%');
            });
        }

        $re = $query
            ->offset($offset)
            ->limit($count)
            ->get()
            ->map(function ($item) {
                return [
                    'id' => $item->id,
                    'name' => $item->name,
                    'mobile' => $item->mobile,
                    'nickname' => $item->nickname,
                ];
            });
        return $this->success($re);
    }
}
